package com.kxq.zhuoyue.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kxq.zhuoyue.config.JdbcTemplateConfig;
import com.kxq.zhuoyue.util.wechat.AccessToken;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.Map;

public class PublicWeChat {
    //获取企业微信的企业号，根据不同企业更改
//    public final static String CORPID = "ww2672529243bc3b9a";
    //    final static String corpsecret = "SrZPeGG2mwkx53BkLXfmhYki_zriq73WXmsPk4JXL0M";


    //获取访问权限码URL
    public final static String ACCESS_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";

    public final static String ACCESS_TOKEN_URL_APPLETS = "https://api.weixin.qq.com/cgi-bin/token";


    private AccessToken getAccessToken(String companyId, String corpsecret, String type) {
        AccessToken token = new AccessToken();
        String url = "";

        //访问微信服务器
        if(type.equals("1"))
            url = ACCESS_TOKEN_URL + "?corpid=" + companyId + "&corpsecret=" + corpsecret;
        else if(type.equals("2"))
            url = ACCESS_TOKEN_URL_APPLETS + "?grant_type=client_credential&appid=" + companyId + "&secret=" + corpsecret;
        try {
            URL getUrl = new URL(url);
            //开启连接，并返回一个URLConnection对象
            HttpURLConnection http = (HttpURLConnection) getUrl.openConnection();
            http.setRequestMethod("GET");
            http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
            //将URL连接用于输入和输出，一般输入默认为true，输出默认为false
            http.setDoOutput(true);
            http.setDoInput(true);
            //进行连接，不返回对象
            http.connect();

            //获得输入内容,并将其存储在缓存区
            InputStream inputStream = http.getInputStream();
            int size = inputStream.available();
            byte[] buffer = new byte[size];
            inputStream.read(buffer);
            //将内容转化为JSON代码
            String message = new String(buffer, "UTF-8");
            JSONObject json = JSONObject.parseObject(message);
            //提取内容，放入对象
            token.setAccess_token(json.getString("access_token"));
            token.setExpires_in(new Integer(json.getString("expires_in")));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //返回access_token码
        return token;
    }

    private String getTokenString(String companyId,String type) {

        String sql = "select company_id,org_id,org_num,app_type,agent_id,app_secret,app_url " +
                " from scrm_company_application where app_type = '"+type+"'" +
                " and company_id = '"+companyId+"'";

        Map<String,Object> reg = JdbcTemplateConfig.jdbcTemplate.queryForMap(sql);

        String corpsecret = reg.get("app_secret").toString();
        String appId = reg.get("agent_id").toString();
        if(type.equals("2")){
            companyId = appId;
        }
        AccessToken accessToken = this.getAccessToken(companyId,corpsecret,type);
        String ACCESS_TOKEN = accessToken.getAccess_token();
        //cacheManager.putCache("accessToken", ACCESS_TOKEN, new Long(accessToken.getExpires_in()));
        return ACCESS_TOKEN;
    }

    public Map<String, Object> pubWeChatUtil(String url,String jsonString,String companyId){
        return pubWeChatUtil(url,jsonString,companyId,"1");
    }

    public Map<String, Object> pubWeChatUtil(String url,String jsonString,String companyId,String type){
        String ACCESS_TOKEN = this.getTokenString(companyId,type);
        String result = "";
        String interfaceUrl = url + ACCESS_TOKEN;
        Map<String,Object> regMap = null;

        try {
            URL postUrl = new URL(interfaceUrl);
            HttpURLConnection http = (HttpURLConnection) postUrl.openConnection();
            http.setRequestMethod("POST");
            http.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            http.setDoOutput(true);
            http.setDoInput(true);
            // 连接超时30秒
            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");
            // 读取超时30秒
            System.setProperty("sun.net.client.defaultReadTimeout", "30000");
            http.connect();

            //写入内容
            OutputStream outputStream = http.getOutputStream();
            if(jsonString != null && jsonString != ""){
                outputStream.write(jsonString.getBytes("UTF-8"));
            }
            InputStream inputStream = http.getInputStream();
            int size = inputStream.available();
            byte[] jsonBytes = new byte[size];
            inputStream.read(jsonBytes);
            result = new String(jsonBytes, "UTF-8");
            regMap = JSON.parseObject(result, Map.class);

            this.isTrue(regMap);

            //清空输出流
            outputStream.flush();
            //关闭输出通道
            outputStream.close();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }


        return JSON.parseObject(result, Map.class);
    }

    private void isTrue(Map<String,Object> regMap) throws Exception{
        int errorcode = (int)regMap.get("errcode");
        String errmsg = regMap.get("errmsg").toString();
        if(errorcode != 0){
            throw new Exception(errmsg);
        }
    }

    public Map<String,Object> getMap(String url,String json,String companyId) throws IOException {
        URL postUrl = new URL(url);
        HttpURLConnection http = (HttpURLConnection) postUrl.openConnection();
        http.setRequestMethod("POST");
        http.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
        http.setDoOutput(true);
        http.setDoInput(true);
        // 连接超时30秒
        System.setProperty("sun.net.client.defaultConnectTimeout", "30000");
        // 读取超时30秒
        System.setProperty("sun.net.client.defaultReadTimeout", "30000");
        http.connect();

        //写入内容
        OutputStream outputStream = http.getOutputStream();
        if(json != null && json != ""){
            outputStream.write(json.getBytes("UTF-8"));
        }
        InputStream inputStream = http.getInputStream();
        int size = inputStream.available();
        byte[] jsonBytes = new byte[size];
        inputStream.read(jsonBytes);
        String result = new String(jsonBytes, "UTF-8");
        Map<String,Object> map = JSON.parseObject(result, Map.class);
        return map;
    }


    /**
     * <pre>
     * Description：GET---有参 (方式一:手动在url后面加上参数)
     * </pre>
     * @param url 例：http:localhost:9400/abc/abc
     * @param params 参数
     * @return {@link String} 返回值
     */
    public String doGetWeChat(String url, String params,String companyId) {
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();

        HttpGet httpGet = null;
        // 创建Get请求
        if ("".equals(params)) {
            httpGet = new HttpGet(url);
        } else {
            // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
            String ACCESS_TOKEN = this.getTokenString(companyId, "1");
            httpGet = new HttpGet(url + "?access_token=" + ACCESS_TOKEN + "&" + params + "&debug=1");
        }
        // 响应模型
        CloseableHttpResponse response = null;
        String result = null;
        try {
            // 配置信息
            RequestConfig requestConfig = RequestConfig.custom()
                    // 设置连接超时时间(单位毫秒)
                    .setConnectTimeout(5000)
                    // 设置请求超时时间(单位毫秒)
                    .setConnectionRequestTimeout(5000)
                    // socket读写超时时间(单位毫秒)
                    .setSocketTimeout(5000)
                    // 设置是否允许重定向(默认为true)
                    .setRedirectsEnabled(true).build();
            // 将上面的配置信息 运用到这个Get请求里
            httpGet.setConfig(requestConfig);
            // 由客户端执行(发送)Get请求
            response = httpClient.execute(httpGet);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                result = EntityUtils.toString(responseEntity);
            }
        } catch (ParseException | IOException e) {
            e.printStackTrace();
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public static PublicWeChat newInstance() {
        return new PublicWeChat();
    }
}
